Skip to content

20260821-linuxkm-WC_SVR_USE_NATIVE_REG_BUFS - #11240

Open
douzzer wants to merge 3 commits into
wolfSSL:masterfrom
douzzer:20260821-linuxkm-WC_SVR_USE_NATIVE_REG_BUFS
Open

20260821-linuxkm-WC_SVR_USE_NATIVE_REG_BUFS#11240
douzzer wants to merge 3 commits into
wolfSSL:masterfrom
douzzer:20260821-linuxkm-WC_SVR_USE_NATIVE_REG_BUFS

Conversation

@douzzer

@douzzer douzzer commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

linuxkm/x86_vector_register_glue.c: add WC_SVR_USE_NATIVE_REG_BUFS: per-CPU
native vector register save buffers, serving hardirq and softirq contexts
where kernel_fpu_begin() is unusable.

previously these contexts were refused (WC_ACCEL_INHIBIT_E): hardirq
outright, softirq whenever !may_use_simd() (pre-6.15, a softirq
interrupting a foreign kernel_fpu section). an exact save/compute/restore
cycle is invisible to the interrupted context and to kernel FPU
bookkeeping, and run-to-completion freezes the blocking condition beneath
the section, so both classes are natively serviceable.

  • per-CPU {softirq, hardirq} state, each {depth, pin_preempt, save_area};
    xsave64/xrstor64 with RFBM 0xe7 & XCR0 (fxsave64 fallback), plain XSAVE
    only; feature detection by direct CPUID/XGETBV, independent of kernel
    cpufeature machinery.

  • recursion is a per-(CPU, class) depth count -- save on the 0->1 edge,
    restore on 1->0; softirq sections hold preempt_disable() (load-bearing
    on PREEMPT_RT).

  • hardirq serves plain saves; softirq serves plain and _MAYBE_INHIBIT
    (its legacy short-circuit is bypassed when native is ready); _INHIBIT,
    hardirq _MAYBE, and NMI keep refusal semantics; task context is
    untouched.

  • wc_svr_native_init() activates in place from
    wc_linuxkm_allocate_svr_states() in any context but NMI -- the FIPS
    pre-Init lazy allocation arrives inside the outermost save's own
    bracket, and wolfCrypt_Init() has been observed with irqs disabled. a
    self-bracketed register round-trip selftest gates wc_svr_native_ready;
    on any failure the long-standing refusal semantics remain fully in
    force.

  • wc_linuxkm_svr_native_is_ready(): runtime readiness accessor for policy
    decisions elsewhere (e.g. the FIPS<v7 default-bank NO_VECTOR_OPS pin).

  • WOLFSSL_LINUXKM_VERBOSE_DEBUG: split the softirq WC_ACCEL_INHIBIT_E
    counter into per-class counters (softirq, hardirq, NMI, other),
    reported at module shutdown.

in non-VERBOSE builds with WC_SVR_DONT_USE_NATIVE_REG_BUFS (or in non-SVR
builds), generated object code is byte-identical to the previous revision.

also add linuxkm/simd_hammer/, a stress testing tool for kernel FPU/SIMD context handling.

tested with

wolfssl-multi-test.sh ...
check-source-text
'.*dev.*cust-kern.*'
'linuxkm-legacy-.*'
quantum-safe-wolfssl-all-crypto-only-intelasm-sp-asm-sp-fips-dev-linuxkm-next-insmod
quantum-safe-wolfssl-all-crypto-only-intelasm-sp-asm-fips-dev-linuxkm-next-clang-tidy

…er-CPU

native vector register save buffers, serving hardirq and softirq contexts
where kernel_fpu_begin() is unusable.

previously these contexts were refused (WC_ACCEL_INHIBIT_E): hardirq
outright, softirq whenever !may_use_simd() (pre-6.15, a softirq
interrupting a foreign kernel_fpu section).  an exact save/compute/restore
cycle is invisible to the interrupted context and to kernel FPU
bookkeeping, and run-to-completion freezes the blocking condition beneath
the section, so both classes are natively serviceable.

- per-CPU {softirq, hardirq} state, each {depth, pin_preempt, save_area};
  xsave64/xrstor64 with RFBM 0xe7 & XCR0 (fxsave64 fallback), plain XSAVE
  only; feature detection by direct CPUID/XGETBV, independent of kernel
  cpufeature machinery.

- recursion is a per-(CPU, class) depth count -- save on the 0->1 edge,
  restore on 1->0; softirq sections hold preempt_disable() (load-bearing
  on PREEMPT_RT).

- hardirq serves plain saves; softirq serves plain and _MAYBE_INHIBIT
  (its legacy short-circuit is bypassed when native is ready); _INHIBIT,
  hardirq _MAYBE, and NMI keep refusal semantics; task context is
  untouched.

- wc_svr_native_init() activates in place from
  wc_linuxkm_allocate_svr_states() in any context but NMI -- the FIPS
  pre-Init lazy allocation arrives inside the outermost save's own
  bracket, and wolfCrypt_Init() has been observed with irqs disabled.  a
  self-bracketed register round-trip selftest gates wc_svr_native_ready;
  on any failure the long-standing refusal semantics remain fully in
  force.

- wc_linuxkm_svr_native_is_ready(): runtime readiness accessor for policy
  decisions elsewhere (e.g. the FIPS<v7 default-bank NO_VECTOR_OPS pin).

- WOLFSSL_LINUXKM_VERBOSE_DEBUG: split the softirq WC_ACCEL_INHIBIT_E
  counter into per-class counters (softirq, hardirq, NMI, other),
  reported at module shutdown.

in non-VERBOSE builds with WC_SVR_DONT_USE_NATIVE_REG_BUFS (or in non-SVR
builds), generated object code is byte-identical to the previous revision.
@douzzer douzzer self-assigned this Aug 21, 2026
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

@douzzer

douzzer commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

retest this please
(no logs)

@douzzer

douzzer commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

retest this please
(no logs)
(clean check-source-text and no changes outside the kernel...)

@kaleb-himes kaleb-himes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passed the battery of tests thrown at it. Sha 256 was a little slow under load but I think that will get cleaned up by the coming ASM fixes so not holding the PR up over it.

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #11240

Scan targets checked: linuxkm-bugs, linuxkm-src, wolfcrypt-bugs, wolfcrypt-rs-bugs, wolfcrypt-src

Findings: 6
6 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Comment thread linuxkm/lkcapi_sha_glue.c

#if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0)
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && \
!defined(WC_SVR_USE_NATIVE_REG_BUFS) && \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIPSv7 default-bank NO_VECTOR_OPS pin gated on compile-time WC_SVR_USE_NATIVE_REG_BUFS instead of runtime readiness · Logic errors

The pin is compiled out whenever WC_SVR_USE_NATIVE_REG_BUFS is built in, but native service can fail at runtime (no XSAVE/FXSR, allocation failure, selftest failure). On such boots linuxkm_get_drbg() still sets WC_RNG_BANK_FLAG_NO_VECTOR_OPS only in non-blockable contexts, so a FIPS v5/v6 wc_Sha256 DRBG instance alternates between asm and C mid-object — the exact breakage the pin prevents. linuxkm_get_drbg() at line 2211 already uses the runtime accessor.

Related known finding #7893 (similar but distinct): Both involve Linux DRBG default-bank startup state, but the candidate faults in wc_linuxkm_rng_bank_init's vector-operation flag selection when native register buffers are unavailable at runtime; #7893 faults in wc_linuxkm_drbg_startup's missing rollback after later failures. The root causes and corrective patches are distinct.

Fix: Keep the block compiled under WC_SVR_USE_NATIVE_REG_BUFS and gate the pin at runtime with !wc_linuxkm_svr_native_is_ready(), mirroring linuxkm_get_drbg().

Comment thread linuxkm/linuxkm_wc_port.h
#if defined(WC_SVR_DONT_USE_NATIVE_REG_BUFS)
#undef WC_SVR_USE_NATIVE_REG_BUFS
#elif defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && !defined(WC_SVR_USE_NATIVE_REG_BUFS)
#define WC_SVR_USE_NATIVE_REG_BUFS

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WC_SVR_USE_NATIVE_REG_BUFS is auto-defined on non-x86, but its implementation and declaration are CONFIG_X86-only · LKCAPI interface correctness

The auto-define keys only on WOLFSSL_USE_SAVE_VECTOR_REGISTERS, which is also set for the ARM path at line 258. wc_linuxkm_svr_native_is_ready() is declared only inside the defined(CONFIG_X86) block at line 746 and defined only in x86_vector_register_glue.c, so the #ifdef WC_SVR_USE_NATIVE_REG_BUFS call at lkcapi_sha_glue.c:2211 has no declaration or symbol on ARM linuxkm builds.

Fix: Add && defined(CONFIG_X86) to the #elif condition that auto-defines WC_SVR_USE_NATIVE_REG_BUFS.

Comment thread linuxkm/lkcapi_sha_glue.c

#if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0)
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && \
!defined(WC_SVR_USE_NATIVE_REG_BUFS) && \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIPS7 default-bank NO_VECTOR_OPS pin is dropped on a compile-time macro rather than runtime native readiness · Cryptographic correctness

WC_SVR_USE_NATIVE_REG_BUFS only means the native save path is compiled in; wc_svr_native_ready stays 0 when the CPU lacks XSAVE/FXSR, the GFP_ATOMIC save-buffer allocation fails, or wc_svr_native_selftest() fails. In those builds the bank-level pin is gone while native never serves, so bankref checkouts via wc_local_rng_bank_checkout_for_bankref() (which sets no per-call NO_VECTOR_OPS) run unpinned. The sibling site linuxkm_get_drbg() at line 2211 correctly uses the runtime accessor.

Related known finding #7929 (similar but distinct): Both affect LinuxKM DRBG/default-bank initialization in lkcapi_sha_glue.c and can leave default-RNG behavior unsafe or inconsistent. However, #7929 faults after DRBG registration by omitting rollback on later startup failures, while this finding selects vector-operation pinning from compile-time availability instead of runtime native readiness; the operations, root causes, and patches differ.

Fix: Keep the FIPS<7 branch compiled in and gate the pin at runtime on !wc_linuxkm_svr_native_is_ready() instead of the build-time macro.

Comment thread linuxkm/lkcapi_sha_glue.c

#if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0)
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && \
!defined(WC_SVR_USE_NATIVE_REG_BUFS) && \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIPSv7 NO_VECTOR_OPS pin is gated at compile time instead of on runtime native readiness · Logic errors

The WC_RNG_BANK_FLAG_NO_VECTOR_OPS pin is now suppressed whenever WC_SVR_USE_NATIVE_REG_BUFS is merely compiled in. Native service can fail to come up at runtime (no XSAVE/FXSR, allocation failure, selftest failure in wc_svr_native_init()), and the pin is then dropped anyway, reintroducing mid-object asm/C switching that FIPS v5/v6 SHA-2 cannot survive. linuxkm_get_drbg() in the same file uses the runtime accessor.

Fix: Keep the #if on WOLFSSL_USE_SAVE_VECTOR_REGISTERS && HAVE_FIPS && FIPS_VERSION3_LT(7,0,0) and add a runtime !wc_linuxkm_svr_native_is_ready() condition to the if.

return 1;
}
#endif /* WC_SVR_USE_NATIVE_REG_BUFS */
#ifdef DEBUG_VECTOR_REGISTER_ACCESS_HARDIRQ_INFO

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New DEBUG_VECTOR_REGISTER_ACCESS_HARDIRQ_INFO macro not registered in .wolfssl_known_macro_extras · Incorrect macro expansion

DEBUG_VECTOR_REGISTER_ACCESS_HARDIRQ_INFO is introduced at lines 505 and 607 but is defined nowhere in the tree. Its siblings DEBUG_VECTOR_REGISTER_ACCESS_ALWAYS_ON/OFF are listed in .wolfssl_known_macro_extras:255-256; this PR adds CONFIG_X86_64 and WC_SVR_DONT_USE_NATIVE_REG_BUFS there but omits this one, so the unknown-macro check flags it.

Fix: Add DEBUG_VECTOR_REGISTER_ACCESS_HARDIRQ_INFO to .wolfssl_known_macro_extras.

Comment thread linuxkm/lkcapi_sha_glue.c

#if defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0)
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && \
!defined(WC_SVR_USE_NATIVE_REG_BUFS) && \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIPS7 default-bank NO_VECTOR_OPS pin is dropped at compile time instead of on runtime native readiness · Preprocessor-conditional security bypass

The pin is gated on !defined(WC_SVR_USE_NATIVE_REG_BUFS), which the header defines for every SVR build. When wc_svr_native_init() bails out (no XSAVE/FXSR, allocation failure, or selftest mismatch at x86_vector_register_glue.c:1579), wc_svr_native_ready stays 0 and the old refusal semantics remain in force, yet the pin is already gone. linuxkm_get_drbg() at line 2211 makes the identical policy decision via the runtime accessor.

Related known finding #7929 (similar but distinct): Both affect LinuxKM DRBG/default-bank startup in the same file, but the candidate faults in wc_linuxkm_rng_bank_init's NO_VECTOR_OPS policy gate when native vector readiness fails; #7929 faults in wc_linuxkm_drbg_startup rollback after later registration failures. Their root causes and corrective patches are different.

Fix: Gate the pin on wc_linuxkm_svr_native_is_ready() at runtime, as linuxkm_get_drbg() does, rather than on the compile-time macro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants